#!/usr/bin/python3
# -*- coding: UTF-8 -*-


# 每次均要核对统计局给的表格列名
# 必须按以下列顺序
# A     B          C                D            E          F          G
# 县区	项目名称	登记注册统计类别	企业控股情况	隶属关系	建设性质	期末项目建设状态

# H           I          J            K             L
# 项目行业代码  计划总投资  累计完成投资   本年完成投资	   建安工程

# 只和上个月的数据进行计算，获取当月完成投资，不再计算去年了
# 去年的数据算出来也不含省返，数据没有意义
#
#

import pandas as pd
import openpyxl
import openpyxl.utils.dataframe as dataframe_utils
import sys
import argparse
from rich import print as rprint
from pathlib import Path

sys.path.append("../lib")
from inner_util import prepare_dir, try_file_path


INDUSTRY_CODE_MAP = {
    1: "农业",
    2: "林业",
    3: "畜牧业",
    4: "渔业",
    5: "农、林、牧、渔专业及辅助性活动",
    6: "煤炭开采和洗选业",
    7: "石油和天然气开采业",
    8: "黑色金属矿采选业",
    9: "有色金属矿采选业",
    10: "非金属矿采选业",
    11: "开采专业及辅助性活动",
    12: "其他采矿业",
    13: "农副食品加工业",
    14: "食品制造业",
    15: "酒、饮料和精制茶制造业",
    16: "烟草制品业",
    17: "纺织业",
    18: "纺织服装、服饰业",
    19: "皮革、毛皮、羽毛及其制品和制鞋业",
    20: "木材加工和木、竹、藤、棕、草制品业",
    21: "家具制造业",
    22: "造纸和纸制品业",
    23: "印刷和记录媒介复制业",
    24: "文教、工美、体育和娱乐用品制造业",
    25: "石油、煤炭及其他燃料加工业",
    26: "化学原料和化学制品制造业",
    27: "医药制造业",
    28: "化学纤维制造业",
    29: "橡胶和塑料制品业",
    30: "非金属矿物制品业",
    31: "黑色金属冶炼和压延加工业",
    32: "有色金属冶炼和压延加工业",
    33: "金属制品业",
    34: "通用设备制造业",
    35: "专用设备制造业",
    36: "汽车制造业",
    37: "铁路、船舶、航空航天和其他运输设备制造业",
    38: "电气机械和器材制造业",
    39: "计算机、通信和其他电子设备制造业",
    40: "仪器仪表制造业",
    41: "其他制造业",
    42: "废弃资源综合利用业",
    43: "金属制品、机械和设备修理业",
    44: "电力、热力生产和供应业",
    45: "燃气生产和供应业",
    46: "水的生产和供应业",
    47: "房屋建筑业",
    48: "土木工程建筑业",
    49: "建筑安装业",
    50: "建筑装饰、装修和其他建筑业",
    51: "批发业",
    52: "零售业",
    53: "铁路运输业",
    54: "道路运输业",
    55: "水上运输业",
    56: "航空运输业",
    57: "管道运输业",
    58: "多式联运和运输代理业",
    59: "装卸搬运和仓储业",
    60: "邮政业",
    61: "住宿业",
    62: "餐饮业",
    63: "电信、广播电视和卫星传输服务",
    64: "互联网和相关服务",
    65: "软件和信息技术服务业",
    66: "货币金融服务",
    67: "资本市场服务",
    68: "保险业",
    69: "其他金融业",
    70: "房地产业",
    71: "租赁业",
    72: "商务服务业",
    73: "研究和试验发展",
    74: "专业技术服务业",
    75: "科技推广和应用服务业",
    76: "水利管理业",
    77: "生态保护和环境治理业",
    78: "公共设施管理业",
    79: "土地管理业",
    80: "居民服务业",
    81: "机动车、电子产品和日用产品修理业",
    82: "其他服务业",
    83: "教育",
    84: "卫生",
    85: "社会工作",
    86: "新闻和出版业",
    87: "广播、电视、电影和录音制作业",
    88: "文化艺术业",
    89: "体育",
    90: "娱乐业",
    91: "中国共产党机关",
    92: "国家机构",
    93: "人民政协、民主党派",
    94: "社会保障",
    95: "群众团体、社会团体和其他成员组织",
    97: "国际组织",
}


# 工业的行业代码06-46
INDUSTRY_CODES = [x for x in range(6, 47)]

# 能源工业投资行业代码
ENERGY_CODES = [6, 7, 25, 44, 45]

# 能源外工业投资行业代码
EXCLUDE_ENERGY_INDUSTRY_CODES = list(
    filter(lambda x: x not in ENERGY_CODES, INDUSTRY_CODES)
)

# 卷烟及配套产业行业代码
CIGARETTE_CODES = [16]
# 生物医药产业行业代码
MEDICINE_CODES = [27]
# 钢铁行业代码
STEEL_CODES = [31]
# 先进制造业行业代码
ADVANCE_MANUFACTURING_CODES = [x for x in range(34, 41)]


# 民间投资看D列企业控股情况
MINGJIAN_CODES = [2, 3, 9]

DIST_DIR = "dist"
SRC_DIR = "src"


print("行业代码")
print("工业06-46", INDUSTRY_CODES)
print("能源以外工业", EXCLUDE_ENERGY_INDUSTRY_CODES)

print("-------------------------------------------")


def usage():
    print("""Usage: 
python3 analysis_v2.py <yearmonth>
python3 analysis_v2.py 202501""")
    print("""
# A     B          C                D            E          F          G                H
# 县区	项目名称	登记注册统计类别	企业控股情况	隶属关系	建设性质	期末项目建设状态	项目行业编码

# I          J            K             L
# 计划总投资  累计完成投资	 本年完成投资	 建安工程
          
""")
    quit()


def wan2yi(val: float) -> float:
    """将万转换为亿"""
    return round(val / 10000, 1)


def calc_percent(a: float, b: float) -> str:
    """计算百分比"""
    return f"{a / b * 100:.1f}%" if b != 0 else "0.0%"


class Industry:
    def __init__(self, year_month):
        self.file_path = Path(SRC_DIR, f"{year_month}.xlsx")

        self.year = int(year_month[:4])
        self.month = int(year_month[4:6])

        rprint(self.__class__.__name__, self.__dict__)

        names = [
            "A",
            "B",
            "C",
            "D",
            "E",
            "F",
            "G",
            "H",
            "I",
            "J",
            "K",
            "L",
        ]
        try:
            self.df = pd.read_excel(self.file_path, sheet_name=0, header=0, names=names)
        except FileNotFoundError as e:
            # 如果没有文件，报错
            print("ERROR", e)
            self.df = None
            raise e

    def get_last_year_self(self):
        """返回去年的Industry实例"""

        last_year = self.year - 1
        month = str(self.month).zfill(2)
        year_month = f"{last_year}{month}"

        try:
            return Industry(year_month)
        except Exception:
            return None

    def get_last_month_self(self):
        """返回上个月的Industry实例"""
        last_month = str(self.month - 1).zfill(2)
        year_month = f"{self.year}{last_month}"
        try:
            return Industry(year_month)
        except Exception:
            return None

    def filter_by_col(self, filter_array, col_name):
        """
        按某列过滤值是否在数组内
        """
        # 统计的表行业代码是4位数，所以要取前两位
        # self.df[col] // 100 就是取前两位
        return self.df.loc[(self.df[col_name] // 100).isin(filter_array)]

    def _sum_col(self, codes_array, col_name="K"):
        """
        按行业分类筛选后计算另一列的和
        默认是本年完成投资K列求和
        """
        # 根据H列行业代码筛选后求和
        ind_df = self.filter_by_col(codes_array, "H")
        return wan2yi(ind_df[col_name].sum())

    def _count_col(self, codes_array, col_name="B"):
        """
        按某列计数，计算项目个数
        默认是项目名称B列
        """
        ind_df = self.filter_by_col(codes_array, "H")
        return ind_df[col_name].count()

    def calc_this_year(self, codes):
        return self._sum_col(codes, "K")

    def calc_from_last_month(self, name, codes):
        """计算工业投资和能源外工业投资当月数字"""
        cur = self.calc_this_year(codes)
        prev, add = 0, 0

        last_month = self.get_last_month_self()
        if last_month is not None:
            prev = last_month.calc_this_year(codes)
            add = round(cur - prev, 1)
        print(
            f"{self.year}年{self.month}月{name}累计完成{cur}亿元，上月累计完成{prev}亿元，当月新增{add}亿元"
        )
        return (cur, prev, add)

    def calc_from_last_year(self, name, codes):
        """计算工业投资和能源外工业投资同比增长数字"""
        cur = self.calc_this_year(codes)
        prev = 0
        add = 0
        last_year = self.get_last_year_self()
        if last_year is not None:
            prev = last_year._sum_col(codes, "K")
            add = calc_percent(cur - prev, prev)

        print(
            f"{self.year}年{self.month}月{name}累计完成{cur}亿元，去年同期完成{prev}亿元，同比增长{add}"
        )
        return (cur, prev, add)

    def cut_investment_level(self):
        """项目总投资分档"""
        # 1亿元以上项目
        gongye_df = self.filter_by_col(INDUSTRY_CODES, "H")

        s1 = gongye_df[gongye_df["I"] >= 10000]["B"]
        s1_count = s1.count()
        print(f"1亿元以上项目{s1_count}个")

        res = pd.cut(
            x=gongye_df["I"],
            bins=[10000, 100000, 300000, 10000000],
            labels=["1-10亿元", "10-30亿元", "30亿元以上"],
            right=False,
            include_lowest=True,
        ).value_counts()

        print(f"1-10亿元项目{res.iloc[0]}个")
        print(f"10-30亿元项目{res.iloc[1]}个")
        print(f"30亿元以上项目{res.iloc[2]}个")

    def save_as(self, df, file_path):
        """输出dataframe样式的表格"""
        rows = dataframe_utils.dataframe_to_rows(df, index=False, header=False)

        wb = openpyxl.Workbook()
        ws = wb.active

        head = [
            "县区",
            "项目名称",
            "登记注册统计类别",
            "企业控股情况",
            "隶属关系",
            "建设性质",
            "期末项目建设状态",
            "项目行业代码",
            "计划投资",
            "累计投资",
            "本年完成投资",
            "建安投资",
        ]
        ws.append(head)
        for row in rows:
            ws.append(row)

        # for cell in ws["A"] + ws[1]:
        #     cell.style = "Pandas"

        wb.save(try_file_path(file_path))
        wb.close()


def 计算项目个数和当月完成投资(ind: Industry):
    工业投资在库项目个数 = ind._count_col(INDUSTRY_CODES)

    a1, _, c1 = ind.calc_from_last_month("工业投资", INDUSTRY_CODES)

    p1 = f"玉溪市工业在库项目共{工业投资在库项目个数}个，{ind.month}月当月完成投资{c1}亿元。"

    能源外工业投资项目个数 = ind._count_col(EXCLUDE_ENERGY_INDUSTRY_CODES)
    a2, _, c2 = ind.calc_from_last_month(
        "能源以外工业投资", EXCLUDE_ENERGY_INDUSTRY_CODES
    )

    p2 = f"玉溪市能源外工业在库项目共{能源外工业投资项目个数}个，{ind.month}月当月完成投资{c2}亿元。"

    能源外工业投资占比 = calc_percent(a2, a1)
    能源外工业投资项目个数占比 = calc_percent(c2, c1)

    gongye_df = ind.filter_by_col(INDUSTRY_CODES, "H")

    mingjian_df = gongye_df.loc[gongye_df["D"].isin(MINGJIAN_CODES)]

    民间投资 = wan2yi(mingjian_df["K"].sum())
    民间投资项目个数 = mingjian_df["B"].count()

    民间投资额占比 = calc_percent(民间投资, a1)
    民间投资项目个数占比 = calc_percent(民间投资项目个数, 工业投资在库项目个数)

    p3 = f"能源以外工业投资项目投资额占比{能源外工业投资占比}、投资项目个数占比{能源外工业投资项目个数占比}，工业投资中民间投资项目投资额占比{民间投资额占比}、项目个数占比{民间投资项目个数占比}。"

    print("-------------------------------------------")
    print(p1)
    print(p2)
    print(p3)


def 计算重点行业完成投资(ind: Industry):
    卷烟投资 = ind._sum_col(CIGARETTE_CODES)
    钢铁投资 = ind._sum_col(STEEL_CODES)
    生物医药投资 = ind._sum_col(MEDICINE_CODES)
    先进制造业投资 = ind._sum_col(ADVANCE_MANUFACTURING_CODES)
    paragraph = f"玉溪市{ind.year}年1-{ind.month}月卷烟及配套产业完成投资{卷烟投资}亿元；钢铁行业完成投资{钢铁投资}亿元；生物医药产业完成投资{生物医药投资}亿元；先进制造业完成投资{先进制造业投资}亿元。"
    print(paragraph)


def 投资最大的项目(ind: Industry, col="K", last_n=30):
    """
    根据选择的列不同
    K列表示当年完成投资数额最大
    J列表示总投资最大
    """
    goneye_df = ind.filter_by_col(INDUSTRY_CODES, "H")
    res = goneye_df.nlargest(last_n, col)
    stat_df = res[["B", "H", col]]

    stat_df.to_excel(f"{ind.year}年1-{ind.month}月_{col}列_投资最大的项目.xlsx")

    print(stat_df)


def 分析投资行业(ind: Industry):
    goneye_df = ind.filter_by_col(INDUSTRY_CODES, "H")

    # suliao = ind.filter_by_col([29])
    # print(suliao)

    adf = goneye_df.copy()

    adf["AA"] = adf["H"].apply(lambda x: INDUSTRY_CODE_MAP.get(x // 100))
    stat_df = adf.copy()

    grouped_sum = stat_df.groupby("AA")["K"].sum()
    sorted_grouped_sum = grouped_sum.sort_values(ascending=False)

    print(sorted_grouped_sum)

    sorted_grouped_sum.to_excel(f"{ind.year}年1-{ind.month}月_各行业投资情况.xlsx")


def parse_args():
    parser = argparse.ArgumentParser(description="分析统计表格")
    parser.add_argument("year_month")

    return parser.parse_args()


def main():
    args = parse_args()

    rprint("Args", args)

    prepare_dir(DIST_DIR)

    ind_cls = Industry(args.year_month)

    # ind_cls.calc_last_month("工业投资", INDUSTRY_CODES)
    # ind_cls.calc_last_month("能源以外工业投资", EXCLUDE_ENERGY_INDUSTRY_CODES)

    计算项目个数和当月完成投资(ind_cls)

    # 计算重点行业完成投资(ind_cls)

    分析投资行业(ind_cls)

    # 投资最大的项目(ind_cls)

    print("--------------------------------------")

    print("问统计局5个数记录在表里")
    print(f"""2025年1-{ind_cls.month}月工业投资完成xx亿元，同比增长xx%，占产业投资比重xx%
能源以外工业投资完成xx亿元，同比增长xx%。""")

    print("Done")


if __name__ == "__main__":
    main()
